/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package scanner;

import Modele.Port;
import java.util.ArrayList;
import swing.ScanneurInterface;

/**
 *
 * @author steven
 */
public class ScanneurClient {

    private ScanneurInterface scanneurInterface;
    /**
     * Contient la liste des Thread actif a un temp t
     */
    private ArrayList<AbstractScanneur> listThread;
    /**
     * Liste des ports a scanner
     */
    private ArrayList<Port> listPorts;
    /**
     * Nombre de Threads actif max a un temp t
     */
    private int tailleFenetre;
    /**
     * true: le client va scanner un intervale de port false: Le client va
     * scanner une liste de ports personnalisee
     */
    private boolean typeScan;

    public ScanneurClient(ScanneurInterface scanneurInterface, ArrayList<Port> olistPorts, int oTailleFenetre, boolean oTypeScan) {
        this.scanneurInterface = scanneurInterface;
        this.listPorts = olistPorts;
        this.tailleFenetre = oTailleFenetre;
        this.typeScan = oTypeScan;
        this.listThread = new ArrayList<AbstractScanneur>();
        updateInfoInterfaceDebutScan();
        initThread();
    }

    /**
     * initialise les thread tant que la
     * liste de port < taille fenetre
     */
    private void initThread() {
        for (int i = 1; i <= tailleFenetre && !listPorts.isEmpty(); i++) {
            Port p = listPorts.get(0);
            AbstractScanneur as = null;
            if (p.isTCP()) {
                as = new ScanneurTCP(this, scanneurInterface.getjTextFieldHote().getText(), p);
            } else {
                as = new ScanneurUDP(this, scanneurInterface.getjTextFieldHote().getText(), p);
            }
            listPorts.remove(p);
            startThread(as);
        }
    }

    /**
     * 
     * @param as  le Thread a ajouter a la liste
     */
    private synchronized void startThread(AbstractScanneur as) {
        listThread.add(as);
        as.start();
    }

    /**
     * Stop le scan en cour de progression
     */
    public void arreterScan() {
        listPorts.clear();
        updateInfoInterfaceFinScan();
    }

    /**
     * supprime le thread passe en parametre
     * 
     * si la liste de port est non vide
     *      on prend le premier thread de la liste 
     *      pour l'affecter a un Thread afin de le scanner
     * 
     * si la liste de Thread actif est vide
     *      on met a jour l'interface
     * 
     * @param as le Thread a enlever de la liste
     */
    public synchronized void updateCompteurThread(AbstractScanneur as) {

        listThread.remove(as);//on enleve le Thread de le liste
        if (!listPorts.isEmpty()) {
            Port p = listPorts.get(0);//on recupere le premier element
            AbstractScanneur newAs = null;
            if (p.isTCP()) {
                newAs = new ScanneurTCP(this, scanneurInterface.getjTextFieldHote().getText(), p);
            } else {
                newAs = new ScanneurUDP(this, scanneurInterface.getjTextFieldHote().getText(), p);
            }
            listPorts.remove(p);
            startThread(newAs);
        }
        if (listThread.isEmpty()) {
            updateInfoInterfaceFinScan();
        }
        scanneurInterface.getjProgressBar1().setValue(scanneurInterface.getjProgressBar1().getValue() + 1);
    }

    /**
     * Met a jour les informations de l'interface
     * au demarrage d'un scan:
     * 
     * Met a jour la progressBar de l'interface
     * Met a jour le champ "information" de l'interface
     */
    private void updateInfoInterfaceDebutScan() {
        scanneurInterface.getjProgressBar1().setMinimum(0);
        scanneurInterface.getjProgressBar1().setValue(0);
        scanneurInterface.getjProgressBar1().setMaximum(listPorts.size());
        scanneurInterface.getjLabelInformations().setText("Le scan est en cour...");
    }

    /**
     * Met a jour les informations de l'interface
     * a la fin d'un scan:
     * 
     * Met a jour la progressBar de l'interface
     * Met a jour le champ "information" de l'interface
     */
    private void updateInfoInterfaceFinScan() {
        scanneurInterface.getScanneurIntervalleButton().setText("SCANNER");
        scanneurInterface.getScanneurListButton().setText("SCANNER LISTE");
        scanneurInterface.getjLabelInformations().setText("Le scan est terminé !");
    }

    /**
     * Affiche le resultat du scan dans l'interface
     * @param p le port scanné a afficher
     */
    public synchronized void ajouterNotification(Port p) {
        scanneurInterface.ajouterNotification(p);
    }

    /**
     * 
     * @return true si on scan un intervalle de port
     *          false si on scan une liste de ports
     */
    public boolean isIntervalleScan() {
        return typeScan;
    }
}
